package com.example.copyonwrite.arraylist;

import java.util.ListIterator;

public class MyCopyOnWriteArrayList<T> {

    private transient volatile Object[] data;

    public MyCopyOnWriteArrayList() {
        data = new Object[0];
    }

    public void add(T element) {
        synchronized (this) {
            Object[] newData = new Object[data.length + 1];
            System.arraycopy(data, 0, newData, 0, data.length);
            newData[data.length] = element;
            data = newData;
        }
    }

    public void set(int index, T element) {
        synchronized (this) {
            T curData = (T) data[index];
            if (curData != element) {
                Object[] newData = new Object[data.length];
                System.arraycopy(data, 0, newData, 0, data.length);
                newData[index] = element;
                data = newData;
            }
        }
    }

    public void remove(int index) {
        synchronized (this) {
            Object[] newData = new Object[data.length - 1];
            if (index == data.length - 1) {
                System.arraycopy(data, 0, newData, 0, data.length - 1);
                data = newData;
            } else {
                System.arraycopy(data, 0, newData, 0, index);
                System.arraycopy(data, index + 1, newData, index, data.length - 1 - index);
                data = newData;
            }
        }
    }

    public T get(int index) {
        return (T) data[index];
    }

    public static void main(String[] args) {

    }

    static class MyCowIterator<T> implements ListIterator<T> {
        @Override
        public boolean hasNext() {
            return false;
        }

        @Override
        public T next() {
            return null;
        }

        @Override
        public boolean hasPrevious() {
            return false;
        }

        @Override
        public T previous() {
            return null;
        }

        @Override
        public int nextIndex() {
            return 0;
        }

        @Override
        public int previousIndex() {
            return 0;
        }

        @Override
        public void remove() {

        }

        @Override
        public void set(T t) {

        }

        @Override
        public void add(T t) {

        }
    }
}
